<template>
  <div class="editor-container">
    <!-- 左侧组件区域 -->
    <div class="left-panel">
      <h3>组件</h3>
      <div class="component-list">
        <button class="component-item" @click="addText">添加文本</button>
        <button class="component-item" @click="addImage">添加图片</button>
        <button class="component-item" @click="addRectangle">添加矩形</button>
        <button class="component-item" @click="addCircle">添加圆形</button>
      </div>
    </div>
    
    <!-- 中间Canvas展示区域 -->
    <div class="center-panel">
      <canvas 
        ref="canvas" 
        width="800" 
        height="600"
        @mousedown="handleMouseDown"
        @mousemove="handleMouseMove"
        @mouseup="handleMouseUp"
        :style="{ cursor: isOverElement ? 'pointer' : 'default' }"
      ></canvas>
    </div>
    
    <!-- 右侧属性设置区域 -->
    <div class="right-panel">
      <h3>属性设置</h3>
      <div v-if="selectedElementIndex !== -1" class="property-panel">
        <!-- 通用属性：位置 -->
        <div class="property-item">
          <label>X 位置:</label>
          <input v-model="x" type="number" placeholder="X 位置" />
        </div>
        
        <div class="property-item">
          <label>Y 位置:</label>
          <input v-model="y" type="number" placeholder="Y 位置" />
        </div>
        
        <!-- 文本元素特有属性 -->
        <template v-if="elementType === 'text'">
          <div class="property-item">
            <label>文本内容:</label>
            <input v-model="text" placeholder="输入文字" />
          </div>
          
          <div class="property-item">
            <label>字体:</label>
            <select v-model="fontFamily">
              <option value="Arial">Arial</option>
              <option value="Helvetica">Helvetica</option>
              <option value="Times New Roman">Times New Roman</option>
            </select>
          </div>
          
          <div class="property-item">
            <label>字号:</label>
            <input v-model="fontSize" type="number" placeholder="字号" />
          </div>
          
          <div class="property-status">文字已选中</div>
        </template>
        
        <!-- 图片元素特有属性 -->
        <template v-else-if="elementType === 'image'">
          <div class="property-item">
            <label>图片地址:</label>
            <input v-model="imageUrl" placeholder="输入图片URL" />
          </div>
          
          <div class="property-item">
            <label>宽度:</label>
            <input v-model="width" type="number" placeholder="宽度" />
          </div>
          
          <div class="property-item">
            <label>高度:</label>
            <input v-model="height" type="number" placeholder="高度" />
          </div>
          
          <div class="property-status">图片已选中</div>
        </template>
        
        <!-- 矩形元素特有属性 -->
        <template v-else-if="elementType === 'rectangle'">
          <div class="property-item">
            <label>宽度:</label>
            <input v-model="width" type="number" placeholder="宽度" />
          </div>
          
          <div class="property-item">
            <label>高度:</label>
            <input v-model="height" type="number" placeholder="高度" />
          </div>
          
          <div class="property-item">
            <label>颜色:</label>
            <input v-model="color" type="color" />
          </div>
          
          <div class="property-status">矩形已选中</div>
        </template>
        
        <!-- 圆形元素特有属性 -->
        <template v-else-if="elementType === 'circle'">
          <div class="property-item">
            <label>半径:</label>
            <input v-model="radius" type="number" placeholder="半径" />
          </div>
          
          <div class="property-item">
            <label>颜色:</label>
            <input v-model="color" type="color" />
          </div>
          
          <div class="property-status">圆形已选中</div>
        </template>
      </div>
      <div v-else class="no-selection">
        请在画布中选择一个元素
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'

// 定义画布引用
const canvas = ref(null)
// 定义元素类型枚举
const ElementType = {
  TEXT: 'text',
  IMAGE: 'image',
  RECTANGLE: 'rectangle',
  CIRCLE: 'circle'
}

// 定义画布元素数组
const canvasElements = ref([
  {
    id: 1,
    type: ElementType.TEXT,
    text: 'Hello, World!',
    fontFamily: 'Arial',
    fontSize: 30,
    x: 100,
    y: 100,
    isSelected: false
  }
])
// 当前选中的元素索引
const selectedElementIndex = ref(-1)
// 当前编辑的元素属性（用于右侧面板）
const elementType = ref(ElementType.TEXT)
const text = ref('Hello, World!')
const fontFamily = ref('Arial')
const fontSize = ref(30)
const x = ref(100)
const y = ref(100)
const width = ref(100)
const height = ref(100)
const radius = ref(50)
const color = ref('#000000')
const imageUrl = ref('')
// 鼠标是否悬停在元素上
const isOverElement = ref(false)
// 拖拽状态
const isDragging = ref(false)
// 拖拽起始位置
const dragStartX = ref(0)
const dragStartY = ref(0)
// 底图对象
const image = new Image()

// 添加文本的方法
const addText = () => {
  // 创建新的文本元素
  const newX = Math.floor(Math.random() * 400) + 100
  const newY = Math.floor(Math.random() * 300) + 100
  const newId = canvasElements.value.length > 0 ? Math.max(...canvasElements.value.map(el => el.id)) + 1 : 1
  
  // 取消之前选中的元素
  if (selectedElementIndex.value !== -1) {
    canvasElements.value[selectedElementIndex.value].isSelected = false
  }
  
  // 添加新文本元素
  const newElement = {
    id: newId,
    type: ElementType.TEXT,
    text: '新文本',
    fontFamily: 'Arial',
    fontSize: 30,
    x: newX,
    y: newY,
    isSelected: true
  }
  canvasElements.value.push(newElement)
  
  // 更新选中索引和编辑面板数据
  selectedElementIndex.value = canvasElements.value.length - 1
  updateEditingProperties()
  
  // 重新绘制
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
}

// 添加图片的方法
const addImage = () => {
  // 创建新的图片元素
  const newX = Math.floor(Math.random() * 400) + 100
  const newY = Math.floor(Math.random() * 300) + 100
  const newId = canvasElements.value.length > 0 ? Math.max(...canvasElements.value.map(el => el.id)) + 1 : 1
  
  // 取消之前选中的元素
  if (selectedElementIndex.value !== -1) {
    canvasElements.value[selectedElementIndex.value].isSelected = false
  }
  
  // 添加新图片元素
  const newElement = {
    id: newId,
    type: ElementType.IMAGE,
    x: newX,
    y: newY,
    width: 200,
    height: 150,
    imageUrl: '/public/vite.svg', // 默认使用项目中的图片
    isSelected: true
  }
  canvasElements.value.push(newElement)
  
  // 更新选中索引和编辑面板数据
  selectedElementIndex.value = canvasElements.value.length - 1
  updateEditingProperties()
  
  // 重新绘制
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
}

// 添加矩形的方法
const addRectangle = () => {
  // 创建新的矩形元素
  const newX = Math.floor(Math.random() * 400) + 100
  const newY = Math.floor(Math.random() * 300) + 100
  const newId = canvasElements.value.length > 0 ? Math.max(...canvasElements.value.map(el => el.id)) + 1 : 1
  
  // 取消之前选中的元素
  if (selectedElementIndex.value !== -1) {
    canvasElements.value[selectedElementIndex.value].isSelected = false
  }
  
  // 添加新矩形元素
  const newElement = {
    id: newId,
    type: ElementType.RECTANGLE,
    x: newX,
    y: newY,
    width: 150,
    height: 100,
    color: '#3498db',
    isSelected: true
  }
  canvasElements.value.push(newElement)
  
  // 更新选中索引和编辑面板数据
  selectedElementIndex.value = canvasElements.value.length - 1
  updateEditingProperties()
  
  // 重新绘制
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
}

// 添加圆形的方法
const addCircle = () => {
  // 创建新的圆形元素
  const newX = Math.floor(Math.random() * 400) + 100
  const newY = Math.floor(Math.random() * 300) + 100
  const newId = canvasElements.value.length > 0 ? Math.max(...canvasElements.value.map(el => el.id)) + 1 : 1
  
  // 取消之前选中的元素
  if (selectedElementIndex.value !== -1) {
    canvasElements.value[selectedElementIndex.value].isSelected = false
  }
  
  // 添加新圆形元素
  const newElement = {
    id: newId,
    type: ElementType.CIRCLE,
    x: newX,
    y: newY,
    radius: 50,
    color: '#e74c3c',
    isSelected: true
  }
  canvasElements.value.push(newElement)
  
  // 更新选中索引和编辑面板数据
  selectedElementIndex.value = canvasElements.value.length - 1
  updateEditingProperties()
  
  // 重新绘制
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
}

onMounted(() => {
  const ctx = canvas.value.getContext('2d')
  // 加载底图
  image.src =
    'https://www4.bing.com//th?id=OHR.BlueNaxos_ZH-CN7863097040_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp' // 替换为实际的底图路径
  image.onload = () => {
    // 绘制底图
    ctx.drawImage(image, 0, 0, canvas.value.width, canvas.value.height)
    // 绘制所有元素
    drawCanvas(ctx)
  }
})

// 更新编辑面板属性
const updateEditingProperties = () => {
  if (selectedElementIndex.value !== -1) {
    const selectedElement = canvasElements.value[selectedElementIndex.value]
    elementType.value = selectedElement.type
    x.value = selectedElement.x
    y.value = selectedElement.y
    
    // 根据元素类型设置特定属性
    if (selectedElement.type === ElementType.TEXT) {
      text.value = selectedElement.text
      fontFamily.value = selectedElement.fontFamily
      fontSize.value = selectedElement.fontSize
    } else if (selectedElement.type === ElementType.IMAGE) {
      width.value = selectedElement.width
      height.value = selectedElement.height
      imageUrl.value = selectedElement.imageUrl
    } else if (selectedElement.type === ElementType.RECTANGLE) {
      width.value = selectedElement.width
      height.value = selectedElement.height
      color.value = selectedElement.color
    } else if (selectedElement.type === ElementType.CIRCLE) {
      radius.value = selectedElement.radius
      color.value = selectedElement.color
    }
  }
}

// 将编辑面板的属性同步到选中的元素
const syncPropertiesToSelectedElement = () => {
  if (selectedElementIndex.value !== -1) {
    const selectedElement = canvasElements.value[selectedElementIndex.value]
    selectedElement.x = x.value
    selectedElement.y = y.value
    
    // 根据元素类型同步特定属性
    if (selectedElement.type === ElementType.TEXT) {
      selectedElement.text = text.value
      selectedElement.fontFamily = fontFamily.value
      selectedElement.fontSize = fontSize.value
    } else if (selectedElement.type === ElementType.IMAGE) {
      selectedElement.width = width.value
      selectedElement.height = height.value
      selectedElement.imageUrl = imageUrl.value
    } else if (selectedElement.type === ElementType.RECTANGLE) {
      selectedElement.width = width.value
      selectedElement.height = height.value
      selectedElement.color = color.value
    } else if (selectedElement.type === ElementType.CIRCLE) {
      selectedElement.radius = radius.value
      selectedElement.color = color.value
    }
  }
}

const drawCanvas = (ctx) => {
  // 清除之前的内容
  ctx.clearRect(0, 0, canvas.value.width, canvas.value.height)
  // 绘制底图
  ctx.drawImage(image, 0, 0, canvas.value.width, canvas.value.height)
  
  // 绘制所有元素
  canvasElements.value.forEach(element => {
    if (element.type === ElementType.TEXT) {
      drawTextElement(ctx, element)
    } else if (element.type === ElementType.IMAGE) {
      drawImageElement(ctx, element)
    } else if (element.type === ElementType.RECTANGLE) {
      drawRectangleElement(ctx, element)
    } else if (element.type === ElementType.CIRCLE) {
      drawCircleElement(ctx, element)
    }
  })
}

// 绘制文本元素
const drawTextElement = (ctx, element) => {
  // 设置文字样式
  ctx.font = `${element.fontSize}px ${element.fontFamily}`
  // 根据选中状态设置文字颜色
  ctx.fillStyle = element.isSelected ? 'red' : 'black'
  // 绘制文字
  ctx.fillText(element.text, element.x, element.y)
  
  // 如果文字被选中，绘制边框
  if (element.isSelected) {
    // 获取文字宽度
    const textWidth = ctx.measureText(element.text).width
    // 绘制选中边框
    ctx.strokeStyle = 'blue'
    ctx.lineWidth = 2
    ctx.strokeRect(element.x - 5, element.y - element.fontSize + 5, textWidth + 10, element.fontSize + 10)
  }
}

// 绘制图片元素
const drawImageElement = (ctx, element) => {
  // 创建图片对象
  const img = new Image()
  img.src = element.imageUrl
  
  // 绘制图片
  try {
    ctx.drawImage(img, element.x, element.y, element.width, element.height)
  } catch (error) {
    // 如果图片加载失败，绘制占位符
    ctx.fillStyle = '#f1f1f1'
    ctx.fillRect(element.x, element.y, element.width, element.height)
    ctx.fillStyle = '#999'
    ctx.font = '14px Arial'
    ctx.fillText('图片加载中...', element.x + 10, element.y + element.height / 2)
  }
  
  // 如果图片被选中，绘制边框
  if (element.isSelected) {
    ctx.strokeStyle = 'blue'
    ctx.lineWidth = 2
    ctx.strokeRect(element.x - 2, element.y - 2, element.width + 4, element.height + 4)
  }
}

// 绘制矩形元素
const drawRectangleElement = (ctx, element) => {
  // 设置填充颜色
  ctx.fillStyle = element.color
  // 绘制矩形
  ctx.fillRect(element.x, element.y, element.width, element.height)
  
  // 如果矩形被选中，绘制边框
  if (element.isSelected) {
    ctx.strokeStyle = 'blue'
    ctx.lineWidth = 2
    ctx.strokeRect(element.x - 2, element.y - 2, element.width + 4, element.height + 4)
  }
}

// 绘制圆形元素
const drawCircleElement = (ctx, element) => {
  // 设置填充颜色
  ctx.fillStyle = element.color
  // 开始绘制路径
  ctx.beginPath()
  // 绘制圆形
  ctx.arc(element.x, element.y, element.radius, 0, Math.PI * 2)
  // 填充圆形
  ctx.fill()
  
  // 如果圆形被选中，绘制边框
  if (element.isSelected) {
    ctx.strokeStyle = 'blue'
    ctx.lineWidth = 2
    ctx.beginPath()
    ctx.arc(element.x, element.y, element.radius + 2, 0, Math.PI * 2)
    ctx.stroke()
  }
}

// 监听属性的变化，同步到选中元素并重新绘制
watch([text, fontFamily, fontSize, x, y, width, height, radius, color, imageUrl], () => {
  syncPropertiesToSelectedElement()
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
})

// 监听元素数组的变化，重新绘制
watch(canvasElements, () => {
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
}, { deep: true })

// 检查点击位置是否在指定元素区域内
const isPointInElementArea = (element, mouseX, mouseY) => {
  if (element.type === ElementType.TEXT) {
    const ctx = canvas.value.getContext('2d')
    ctx.font = `${element.fontSize}px ${element.fontFamily}`
    const textWidth = ctx.measureText(element.text).width
    const textHeight = element.fontSize
    
    // 文字区域的边界
    const textLeft = element.x
    const textRight = element.x + textWidth
    const textTop = element.y - textHeight
    const textBottom = element.y
    
    // 检查点击位置是否在文字区域内
    return mouseX >= textLeft && mouseX <= textRight && mouseY >= textTop && mouseY <= textBottom
  } else if (element.type === ElementType.IMAGE || element.type === ElementType.RECTANGLE) {
    // 矩形区域的边界
    const rectLeft = element.x
    const rectRight = element.x + element.width
    const rectTop = element.y
    const rectBottom = element.y + element.height
    
    // 检查点击位置是否在矩形区域内
    return mouseX >= rectLeft && mouseX <= rectRight && mouseY >= rectTop && mouseY <= rectBottom
  } else if (element.type === ElementType.CIRCLE) {
    // 计算点击位置到圆心的距离
    const distance = Math.sqrt(Math.pow(mouseX - element.x, 2) + Math.pow(mouseY - element.y, 2))
    
    // 检查点击位置是否在圆形区域内
    return distance <= element.radius
  }
  
  return false
}

// 查找鼠标位置下的元素
const findElementAtPosition = (mouseX, mouseY) => {
  // 从后向前检查（后添加的元素优先选中）
  for (let i = canvasElements.value.length - 1; i >= 0; i--) {
    if (isPointInElementArea(canvasElements.value[i], mouseX, mouseY)) {
      return i
    }
  }
  return -1
}

// 处理鼠标按下事件
const handleMouseDown = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top
  
  // 查找点击位置的元素
  const clickedIndex = findElementAtPosition(mouseX, mouseY)
  
  // 取消之前选中的元素
  if (selectedElementIndex.value !== -1) {
    canvasElements.value[selectedElementIndex.value].isSelected = false
  }
  
  // 更新选中状态
  if (clickedIndex !== -1) {
    canvasElements.value[clickedIndex].isSelected = true
    selectedElementIndex.value = clickedIndex
    updateEditingProperties()
    
    // 开始拖拽
    isDragging.value = true
    // 记录拖拽起始位置
    dragStartX.value = mouseX
    dragStartY.value = mouseY
  } else {
    selectedElementIndex.value = -1
  }
  
  // 重新绘制
  const ctx = canvas.value.getContext('2d')
  drawCanvas(ctx)
}

// 处理鼠标移动事件
const handleMouseMove = (event) => {
  const rect = canvas.value.getBoundingClientRect()
  const mouseX = event.clientX - rect.left
  const mouseY = event.clientY - rect.top
  
  // 如果正在拖拽且有选中的元素
  if (isDragging.value && selectedElementIndex.value !== -1) {
    // 计算鼠标移动的距离
    const deltaX = mouseX - dragStartX.value
    const deltaY = mouseY - dragStartY.value
    
    // 更新元素的位置
    const selectedElement = canvasElements.value[selectedElementIndex.value]
    selectedElement.x += deltaX
    selectedElement.y += deltaY
    
    // 更新编辑面板中的位置值
    x.value = selectedElement.x
    y.value = selectedElement.y
    
    // 更新拖拽起始位置为当前位置
    dragStartX.value = mouseX
    dragStartY.value = mouseY
    
    // 重新绘制
    const ctx = canvas.value.getContext('2d')
    drawCanvas(ctx)
  } else {
    // 检查鼠标是否悬停在任何元素上
    const hoverIndex = findElementAtPosition(mouseX, mouseY)
    isOverElement.value = hoverIndex !== -1
  }
}

// 处理鼠标松开事件
const handleMouseUp = () => {
  // 结束拖拽状态
  isDragging.value = false
}
</script>

<style scoped>
.editor-container {
  display: flex;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

.left-panel {
  width: 200px;
  padding: 15px;
  border-right: 1px solid #ddd;
  background-color: #f5f5f5;
}

.center-panel {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f9f9f9;
  padding: 20px;
  overflow: auto;
}

.right-panel {
  width: 250px;
  padding: 15px;
  border-left: 1px solid #ddd;
  background-color: #f5f5f5;
  overflow-y: auto;
}

h3 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 16px;
  color: #333;
}

.component-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.component-item {
  padding: 8px 12px;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

.component-item:hover {
  background-color: #e6f7ff;
  border-color: #1890ff;
}

.property-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.property-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.property-item label {
  font-size: 14px;
  color: #666;
}

.property-item input,
.property-item select {
  padding: 6px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  width: 100%;
}

.property-status {
  margin-top: 15px;
  padding: 8px;
  background-color: #f0f9eb;
  color: #67c23a;
  border-radius: 4px;
  text-align: center;
}

.no-selection {
  color: #999;
  text-align: center;
  padding: 20px 0;
}

canvas {
  border: 1px solid #ddd;
  background-color: white;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>
